# This code is so you can run the samples without installing the package
import sys
import os
from compiler.ast import Node
#from IPython.utils.traitlets import NoDefaultSpecified
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))

# python
import math

# stdlib
import copy
import random
import weakref

# pyglet related
import pyglet
from pyglet.window import key

# cocos2d related
import cocos
from cocos.euclid import Point2
from cocos import sprite
from cocos.tiles import *

# testrico related
from constants import *

from utils import *
from player import Pacman
from enemies import *

__all__ = ['GameModel']

#
# Model (of the MVC pattern)
#

class GameModel( pyglet.event.EventDispatcher ):

    def __init__(self):
        super(GameModel,self).__init__()
    
        self.bicho = Pacman('fantasma.png')

        
        #cargo el mapa para las colisiones
        #self.tmx_resource = load_tmx('test_collisions.tmx')
        self.tmx_resource = load_tmx('niveles.tmx')
        # levanto las capas del tmx
        self.nivel_1     = self.tmx_resource['nivel_1']
        self.bicho.set_parent_map(self.nivel_1)
        #self.base_map        = self.tmx_resource['base']
        #self.esquinas        = self.tmx_resource['esquinas']
        #self.items        = self.tmx_resource['items']
        # la capa pastillas contiene las pastillitas con el attributo
        # pastilla = 1        
        self.pasti_map        = self.tmx_resource['pastillas']
        
        self.astar_board = tiledmap2board(self.nivel_1, BOARD_START_POINT, BOARD_END_POINT, 'wall')
        
        self.key_pressed = None
        self.cant_pills = 0 

        self.sombra = Sombra('sombra.png')
        self.sombra.set_parent_map(self.nivel_1)
        self.sombra.init_parent_map()

        self.rapido = Rapido('rapido.png')
        self.rapido.set_parent_map(self.nivel_1)
        self.rapido.init_parent_map()

        self.tonto = Tonto('tonto.png')
        self.tonto.set_parent_map(self.nivel_1)
        self.tonto.init_parent_map()

        self.miedoso = Miedoso('miedoso.png')
        self.miedoso.set_parent_map(self.nivel_1)
        self.miedoso.init_parent_map()
        self.miedoso.set_brother(self.sombra)

        self.libre=True
        self.pMatrix = tiledmap2board(self.pasti_map, BOARD_START_POINT, BOARD_END_POINT, 'active')
        # self.pMatrix = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        #                 [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
        #                 [0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0],
        #                 [0,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,0],
        #                 [0,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0],
        #                 [0,3,1,0,1,1,1,1,1,2,1,1,1,1,1,0,1,3,0],
        #                 [0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0],
        #                 [0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0],
        #                 [0,0,0,0,1,0,2,0,0,0,0,0,2,0,1,0,0,0,0],
        #                 [0,0,0,0,1,0,2,2,2,2,2,2,2,0,1,0,0,0,0],
        #                 [0,0,0,0,1,0,2,0,0,0,0,0,2,0,1,0,0,0,0],
        #                 [4,2,2,2,1,2,2,0,2,2,2,0,2,2,1,2,2,2,4],
        #                 [0,0,0,0,1,0,2,0,0,5,0,0,2,0,1,0,0,0,0],
        #                 [0,0,0,0,1,0,2,2,2,2,2,2,2,0,1,0,0,0,0],
        #                 [0,0,0,0,1,0,0,0,2,0,2,0,0,0,1,0,0,0,0],
        #                 [0,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,0],
        #                 [0,1,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0],
        #                 [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
        #                 [0,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0],
        #                 [0,3,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,3,0],
        #                 [0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0],
        #                 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]] 
    
        self.smallPellets = ThingsContainer()
     
        for x in range(18):
            for y in range(21):
                if self.pMatrix[x][y] == 1:
                    smallPellet= SmallPellet('pellet.png')
                    smallPellet.scale=0.5
                    smallPellet.position= Point2((192+(x*TILE_SIZE))+HALF_TILE_SIZE,(TILE_SIZE+(y*TILE_SIZE))+HALF_TILE_SIZE)
                    self.smallPellets.add(smallPellet)

    def set_controller( self, ctrl ):
        self.ctrl = weakref.ref( ctrl )

    def catch_key(self, k):
        self.bicho.pressed=True
        if self.bicho.doblando():
            self.key_pressed=k
        else:
            self.check_key(k)

    def release_key(self, k):
        self.bicho.pressed=False


    def check_key(self, k):
        if k == key.LEFT:
            self.bicho_left()
        elif k == key.RIGHT:
            self.bicho_right()
        elif k == key.DOWN:
            self.bicho_down()
        elif k == key.UP:
            self.bicho_up()


    def bicho_right( self ):
        '''moves the bicho to laderecha'''
        self.bicho.dir_prop = Point2(1, 0)
        self.bicho.dir_prop_copy=self.bicho.dir_prop
        self.dispatch_event("on_move_bicho")

    def bicho_left( self ):
        '''moves the bicho to laizquierda'''
        self.bicho.dir_prop = Point2(-1, 0)
        self.bicho.dir_prop_copy=self.bicho.dir_prop
        self.dispatch_event("on_move_bicho")

    def bicho_down( self ):
        '''moves the bicho to laabajo'''
        self.bicho.dir_prop = Point2(0, -1)
        self.bicho.dir_prop_copy=self.bicho.dir_prop
        self.dispatch_event("on_move_bicho")

    def bicho_up( self ):
        '''moves the bicho to laarriba'''
        self.bicho.dir_prop = Point2(0, 1)
        self.bicho.dir_prop_copy=self.bicho.dir_prop
        self.dispatch_event("on_move_bicho")

    def set_prop_direction(self,k):
        self.check_key(k) 

    # def bicho_stop( self ):
    #     '''stops the bug!'''
    #     self.bicho.vel = Point2(0, 0)
    #     self.dispatch_event("on_stop_bicho")

    # def bicho_turn_right( self ):
    #     current_cell = self.esquinas.get_at_pixel(self.bicho.x,self.bicho.y)
    #     c = current_cell.get

    #     if c('corner'):
    #         if self.bicho.y == current_cell.center[1]:
    #             self.bicho.vel = Point2(self.bicho.speed, 0)
    #             self.dispatch_event("on_move_bicho")

    # def bicho_turn_left( self ):
    #     current_cell = self.esquinas.get_at_pixel(self.bicho.x,self.bicho.y)
    #     c = current_cell.get

    #     if c('corner'):
    #         if self.bicho.y == current_cell.center[1]:
    #             self.bicho.vel = Point2(-self.bicho.speed, 0)
    #             self.dispatch_event("on_move_bicho")

    # def bicho_turn_up( self ):
    #     current_cell = self.esquinas.get_at_pixel(self.bicho.x,self.bicho.y)
    #     c = current_cell.get

    #     if c('corner'):
    #         if self.bicho.x == current_cell.center[0]:
    #             self.bicho.vel = Point2(0, self.bicho.speed)
    #             self.dispatch_event("on_move_bicho")

    # def bicho_turn_down( self ):
    #     current_cell = self.esquinas.get_at_pixel(self.bicho.x,self.bicho.y)
    #     c = current_cell.get

    #     if c('corner'):
    #         if self.bicho.x == current_cell.center[0]:
    #             self.bicho.vel = Point2(0, -self.bicho.speed)
    #             self.dispatch_event("on_move_bicho")

    def playerAgarrado(self, tile_map):
        bichoCell = tile_map.get_at_pixel(self.bicho.x,self.bicho.y)
        #rapidoCell = tile_map.get_at_pixel(self.rapido.x,self.rapido.y)
        sombraCell = tile_map.get_at_pixel(self.sombra.x,self.sombra.y)
        #tontoCell = tile_map.get_at_pixel(self.tonto.x,self.tonto.y)
        #miedosoCell = tile_map.get_at_pixel(self.miedoso.x,self.miedoso.y)
        
        if bichoCell == sombraCell:# or rapidoCell == sombraCell or bichoCell == tontoCell or miedosoCell == bichoCell:
            return True
        return False

    def pillAgarrada(self, pasti_map):
        bichoCell = pasti_map.get_at_pixel(self.bicho.x,self.bicho.y)
        celda = pasti_map.get_cell(bichoCell.i, bichoCell.j)
        if celda.get('active'):
            #print "Hay pasti"
            if celda.__getitem__('active') == 1:
                self.cant_pills+=1
                celda.__setitem__('active', 0)
                #print self.cant_pills
                #celda.active=0
                
        
    def update(self):
        if self.libre:
            if (not self.bicho.doblando() and self.key_pressed):
                self.set_prop_direction(self.key_pressed)
                self.key_pressed = None
            self.bicho.update()
            self.pillAgarrada(self.pasti_map)
            #self.sombra.set_target(Point2(self.bicho.x, self.bicho.y))
            self.sombra.setChaseTarget(self.bicho)
            self.sombra.update()
            self.tonto.setChaseTarget(self.bicho)
            self.tonto.update()
            self.miedoso.setChaseTarget(self.bicho)
            self.miedoso.update()
            self.rapido.setChaseTarget(self.bicho)
            self.rapido.update()
            
            if self.playerAgarrado(self.nivel_1):
                print 'agarrado'
                self.libre=False
        

class Pellet( sprite.Sprite ):
    def __init__(self, image):
        super( Pellet, self).__init__(image)

class SmallPellet( Pellet ):
    def __init__(self, image):
        super( SmallPellet, self).__init__(image)

class BigPellet( Pellet ):
    def __init__(self, image):
        super( BigPellet, self).__init__(image)


# esta clase derivada de BatchableNode, agrega los metodos para updatear
# y dibujar a cada uno de los children.
# Asume que los children tienen los metodos draw y update

class ThingsContainer(cocos.batch.BatchableNode):
    def __init__( self ):
        super( ThingsContainer, self ).__init__()

    def update(self):
        for t in self.get_children():
            t.update()

    def draw(self):
        for t in self.get_children():
            t.draw()

GameModel.register_event_type('on_move_bicho')
GameModel.register_event_type('on_stop_bicho')